package edu.lyun.trainingproject.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.function.Consumer;

/**
 * @Title: Converter
 * @Author: CokeGGts
 * @Date: 2024-10-19 13:43:25
 * @Description: 实体数据转换为视图数据接口
 */
public interface Converter {
    /**
     * @Title: asViewObject
     * @Author: CokeGGts
     * @Date: 2024-10-19 13:44:01
     * @Params: [clazz转化目标对象的类型, consumer消费者函数方法]
     * @Return: V
     * @Description: 将当前类转化为指定视图对象并使用Consumer函数对转化的对象进行包装
     */
    default <V> V asViewObject(Class<V> clazz, Consumer<V> consumer) {
        V v = this.asViewObject(clazz);
        consumer.accept(v);
        return v;
    }

    /**
     * @Title: asViewObject
     * @Author: CokeGGts
     * @Date: 2024-10-19 13:49:34
     * @Params: [clazz转化目标对象的类型]
     * @Return: V
     * @Description: 将当前类转换为指定试图对象, 依赖属性字段匹配
     */
    default <V> V asViewObject(Class<V> clazz) {
        try {
            Field[] declaredFields = clazz.getDeclaredFields();
            Constructor<V> constructor = clazz.getConstructor();
            V v = constructor.newInstance();
            for (Field field : declaredFields) {
                convert(field, v);
            }
            return v;
        } catch (ReflectiveOperationException exception) {
            throw new RuntimeException();
        }
    }

    /**
     * @Title: convert
     * @Author: CokeGGts
     * @Date: 2024-10-19 13:50:51
     * @Params: [field, vo]
     * @Return: void
     * @Description: 设置属性值
     */
    private void convert(Field field, Object vo) {
        try {
            Field source = this.getClass().getDeclaredField(field.getName());
            field.setAccessible(true);
            source.setAccessible(true);
            field.set(vo, source.get(this));
        } catch (NoSuchFieldException | IllegalAccessException ignored) {
        }
    }
}
